package com.tim.helper.string;

import com.tim.MainHelper;
import com.tim.util.SqlAnalysisUtil;
import com.tim.util.StringAnalysisUtil;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;

/**
 * 枚举类转字符串；字符串转枚举类
 *
 */
public class EnumClassHelper {

	/**enum描述；desc-name*/
	@Test
	public void printEnumInfo(){
		// "%3$s-%2$s "
		String template = "{\"type\": \"%2$s\",    \"fileUrl\": \"%3$s\"},";
    String enumCode =
        "YYZZ(\"YYZZ\", \"营业执照\"),\n" +
				"\tYPJY(\"YPJY\", \"药品经营许可证\"),\n" +
				"\tHLWY(\"HLWY\", \"互联网药品信息服务资格证\"),\n" +
				"\tYLQY(\"YLQY\", \"医疗器械经营许可证\"),\n" +
				"\tELYL(\"ELYL\", \"二类医疗器械备案凭证\"),\n" +
				"\tSPJY(\"SPJY\", \"食品经营许可证\"),";
		Arrays.stream(enumCode.trim().split("[\r\n]+"))
				.filter(StringUtils::isNotBlank)
				.map(str->{
					String[] split = str.substring(str.indexOf('(') + 1, str.lastIndexOf(')'))
							.trim().split("[\"\\s,]+");
					return String.format(template, split);
				})
				.forEach(System.out::print);
	}

	/**
	 * 按数据库字段声明信息生成枚举类
	 * 	  `intersection` tinyint(4) NOT NULL COMMENT '是否交差 1未交差 2已交差',
	 * 描述信息按[空格、()（）;；]分割为数组，判定是否包含splitor，切分后为全word匹配的充作枚举名。
	 * 格式：待发货-WAIT_SHIP 已发货-HAS_SHIPPED 已收货-RECEIVED
	 * @author Litianlin
	 * @date 2020年10月12日
	 */
	@Test
	public void genEnumByLine() {
		String splitor = "-";
		String dbLine = ""
				;
		doGenEnum(dbLine, splitor);
	}

	/**
	 * 按信息生成枚举类
	 * 	 1-未交差 2-已交差,
	 * 描述信息按[空格、：:;；]分割为数组，判定是否包含splitor，切分后为全word匹配的充作枚举名。
	 * 格式：待发货-WAIT_SHIP 已发货-HAS_SHIPPED 已收货-RECEIVED
	 * @author Litianlin
	 * @date 2020年10月12日
	 */
	@Test
	public void genEnumByInfo() throws IOException {
		String className="distributionType";
		String info = "配送模式 1、自行配送 2、微信即时配送"
				;
		String splitor = "[-、]+";
		className = StringAnalysisUtil.toPascal(className.contains("_")?className.toLowerCase():className);
		className += className.endsWith("Enum") ? "" : "Enum";
		String classDesc="";
		StringBuilder fields = new StringBuilder();
		String[] split = info.trim().split("[\\s:：;；]+");
		classDesc = split[0];
		for (int i = 1; i < split.length; i++) {
			String[] strs = split[i].split(splitor);
			String template = strs[0].matches("\\w+") ? "\t%1$s(\"%1$s\", \"%2$s\"),"
					: "\t%2$s(\"%2$s\", \"%1$s\"),";
			fields.append(String.format(template, strs))
				.append("\n");

		}

		String content = EnumTemplateService.getTemplate(2).replaceAll("CLASSDESC", classDesc)
				.replace("CLASSDATE", new SimpleDateFormat("yyyy-MM-dd").format(new Date()))
				.replaceAll("CLASSNAME", className)
				.replaceAll("FIELDS", fields.toString());
		System.out.println(content);
		Files.write(Paths.get(MainHelper.OUTPUT_DIR, className+".java"), content.getBytes(StandardCharsets.UTF_8));
	}

	public void genEnumByDDL() {
		String splitor = "-";
		String ddl = "";
		String[] infos = ddl.trim().split("\r\n");
		for (int i = 1; i < infos.length-1; i++) {
			String info = infos[i];
			int flag = info.indexOf("COMMENT");
			if(flag > -1) {
				String desc = info.substring(flag);
				if(desc.contains("1") && desc.contains("2") ) {
					doGenEnum(info, splitor);
					System.out.println();
				}
			}
		}
	}

	private void doGenEnum(String dbLine, String splitor) {
		// 获取枚举类名
		dbLine = dbLine.trim();
		String className = SqlAnalysisUtil.getEnumNameByDbLine(dbLine);
		
		String classDesc = "";
		String[] fieldDescs = null;
		StringBuffer fields = new StringBuffer();
		String commentStr = "COMMENT";
		int flag = dbLine.indexOf(commentStr);
		
		// 
		if(flag > -1) {
			String comment = dbLine.substring(flag+commentStr.length(), dbLine.length()-1)
					.replaceAll(SqlAnalysisUtil.classNameRemoveREG, "").trim();
			String[] infos = comment.split("[\\s+\\(\\)（）；;]");
			classDesc = infos[0];
			fieldDescs = infos;
			for (int i = 1; i < fieldDescs.length; i++) {
				String fieldDescInfo = fieldDescs[i];
				fieldDescInfo = fieldDescInfo.trim();
				String[] strs = fieldDescInfo.split(splitor);
				boolean preIsNum = strs[0].matches("\\d+");
				boolean preIsWord = strs[0].matches("\\w+");
				String fieldStatus, fieldDesc;
				if(preIsWord){
					fieldStatus=strs[0];
					fieldDesc=strs[1].replaceAll(SqlAnalysisUtil.fieldDescRemoveREG, "");
				}else{
					fieldDesc=strs[0];
					fieldStatus=strs[1].replaceAll(SqlAnalysisUtil.fieldDescRemoveREG, "");
				}
				fields.append(fieldTemplate.replaceAll("CLASSNAME", preIsNum?className:"")
					.replaceAll("FIELDSTATUS", fieldStatus)
					.replaceAll("FIELDDESC", fieldDesc));
			}
		}else{
			String comment = dbLine.replaceAll(SqlAnalysisUtil.classNameRemoveREG, "").trim();
			className = "Enum";
			String[] infos = comment.split("[\\s+\\(\\)（）；;]");
			fieldDescs = infos;
			for (int i = 0; i < fieldDescs.length; i++) {
				String fieldDescInfo = fieldDescs[i];
				fieldDescInfo = fieldDescInfo.trim();
				String[] strs = fieldDescInfo.split(splitor);
				boolean preIsNum = strs[0].matches("\\d+");
				boolean preIsWord = strs[0].matches("\\w+");
				String fieldStatus, fieldDesc;
				if(preIsWord){
					fieldStatus=strs[0];
					fieldDesc=strs[1].replaceAll(SqlAnalysisUtil.fieldDescRemoveREG, "");
				}else{
					fieldDesc=strs[0];
					fieldStatus=strs[1].replaceAll(SqlAnalysisUtil.fieldDescRemoveREG, "");
				}
				fields.append(fieldTemplate.replaceAll("CLASSNAME", preIsNum?className:"")
						.replaceAll("FIELDSTATUS", fieldStatus)
						.replaceAll("FIELDDESC", fieldDesc));
			}
		}
		
		System.out.println(EnumTemplateService.getTemplate(2).replaceAll("CLASSDESC", classDesc)
				.replace("CLASSDATE", new SimpleDateFormat("yyyy-MM-dd").format(new Date()))
				.replaceAll("CLASSNAME", className)
				.replaceAll("FIELDS", fields.toString()));
	}

	interface EnumTemplateService {
		String getTemplate();

		static String getTemplate(int type){
			// type：0-懒猪 1-每日说 2-山海平店绩
			return type==0||type==1 ? new XssdImpl().getTemplate()
					: new ShpImpl().getTemplate();
		}
		class XssdImpl implements EnumTemplateService {

			@Override
			public String getTemplate() {
				String template = "import java.util.HashMap;\n" +
						"import com.xqxc.plat.enums.BaseEnumStatus;\n\n" +
						"/**\r\n" +
						" * CLASSDESC\r\n" +
						" * @author Tim\r\n" +
						" * @date CLASSDATE\r\n" +
						" *\r\n" +
						" */\r\n" +
						"public enum CLASSNAME implements BaseEnumStatus{\r\n" +
						"FIELDS" +
						"\t;\r\n" +
						"\r\n" +
						"\tprivate String code;\r\n" +
						"\r\n" +
						"\tprivate String value;\r\n" +
						"\r\n" +
						"\tprivate static final HashMap<String, CLASSNAME> codeValueMap = new HashMap<>();\r\n" +
						"\r\n" +
						"\tstatic {\r\n" +
						"\t\tfor(CLASSNAME type : values()) {\r\n" +
						"\t\t\tcodeValueMap.put(type.getCode(), type);\r\n" +
						"\t\t}\r\n" +
						"\t}\r\n"+
						"\r\n" +
						"    public static String code2Value(String code) {\r\n" +
						"        return codeValueMap.containsKey(code) ? codeValueMap.get(code).getValue() : \"\";\r\n" +
						"    }" +
						"\r\n" +
						"\tpublic static CLASSNAME get(String code) {\r\n" +
						"\t\treturn codeValueMap.containsKey(code) ? codeValueMap.get(code) : null;\r\n" +
						"\t}\r\n"+
						"\r\n" +
						"\tCLASSNAME(String code, String value) {\r\n" +
						"\t\tthis.code = code;\r\n" +
						"\t\tthis.value = value;\r\n" +
						"\t}    \r\n"+
						"\r\n" +
						"\t@Override\r\n" +
						"\tpublic String getCode() {\r\n" +
						"\t\treturn code;\r\n" +
						"\t}\r\n" +
						"\r\n" +
						"\t@Override\r\n" +
						"\tpublic String getValue() {\r\n" +
						"\t\treturn value;\r\n" +
						"\t}	\r\n"+
						"}\r\n"+
						"	";
				return template;
			}
		}
		class ShpImpl implements EnumTemplateService {

			@Override
			public String getTemplate() {
				String template = "import com.baomidou.mybatisplus.annotation.EnumValue;\n" +
						"import lombok.AllArgsConstructor;\n" +
						"import lombok.AccessLevel;\n" +
						"import java.util.HashMap;\n" +
						"import lombok.Getter;\n" +
						"\n" +
						"/**\n" +
						" * CLASSDESC\n" +
						" * @author Tim\n" +
						" * @date CLASSDATE\n" +
						" *\n" +
						" */\n" +
						"@Getter\n" +
						"@AllArgsConstructor(access = AccessLevel.PRIVATE)\n" +
						"public enum CLASSNAME{\n" +
						"FIELDS\t;\n" +
						"\n" +
						"\t@EnumValue\n" +
						"\tprivate String code;\n" +
						"\n" +
						"\tprivate String value;\n" +
						"\n" +
						"\tprivate static final HashMap<String, CLASSNAME> codeValueMap = new HashMap<>();\n" +
						"\n" +
						"\tstatic {\n" +
						"\t\tfor(CLASSNAME type : values()) {\n" +
						"\t\t\tcodeValueMap.put(type.getCode(), type);\n" +
						"\t\t}\n" +
						"\t}\n" +
						"\n" +
						"    public static String code2Value(String code) {\n" +
						"        return codeValueMap.containsKey(code) ? codeValueMap.get(code).getValue() : \"\";\n" +
						"    }\n" +
						"\n" +
						"\tpublic static CLASSNAME get(String code) {\n" +
						"\t\treturn codeValueMap.getOrDefault(code, null);\n" +
						"\t}\n" +
						"\n" +
						"\tpublic boolean codeEquals(String code){\n" +
						"\t\treturn getCode().equals(code);\n" +
						"\t}\n" +
						"\n" +
						"}\n" +
						"\t";
				return template;
			}
		}
	}
	public String fieldTemplate = "   CLASSNAMEFIELDSTATUS(\"FIELDSTATUS\", \"FIELDDESC\"),\r\n";


}
